package com.cqjtu.tto.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.cqjtu.tto.dao.mapper.ScreenshotRecordMapper;
import com.cqjtu.tto.dao.mapper.SysUserMapper;
import com.cqjtu.tto.dao.pojo.ScreenshotRecord;
import com.cqjtu.tto.dao.pojo.SysUser;
import com.cqjtu.tto.vo.ErrorCode;
import com.cqjtu.tto.vo.Results;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.async.DeferredResult;
import sun.misc.BASE64Decoder;
//import org.apache.commons.codec.binary.Base64;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Consumer;

/**
 * 监控请求服务类，长轮询方式实现
 */

@Service
public class DeferredResultService {
    private Map<String, Consumer<Results>> taskMap;

    // 图片保存路径
//    @Value("${screenshot.path}")
    private String path = "D:/Projects/JavaWebCase/real-estate/picture/";
    @Autowired
    private SysUserMapper sysUserMapper;
    @Autowired
    private ScreenshotRecordMapper screenshotRecordMapper;

    public DeferredResultService(){
        taskMap = new ConcurrentHashMap<>();
    }

    /**
     * 将请求ip与setResult映射
     * @param requestIp
     * @param deferredResult
     */
    public void process(String requestIp, DeferredResult<Results> deferredResult){
        // 请求超时的回调函数
        deferredResult.onTimeout( () -> {
            // 从队列中移除该请求
            taskMap.remove(requestIp);
            // 设置超时返回的信息
            deferredResult.setResult(Results.fail(90001,"会话超时"));
        });
        // 判断taskMap是否已有该请求
        Optional.ofNullable(taskMap)
                .filter(t -> !t.containsKey(requestIp))
                .orElseThrow( () -> new IllegalArgumentException(String.format("requestIp=%s is existing", requestIp)));
        // 将请求放到队列中
        taskMap.putIfAbsent(requestIp, deferredResult::setResult);
    }

    /**
     * 执行异步操作
     * @param requestIp
     * @param result
     */
    public void settingResult(String requestIp, Results result){
        if (taskMap.containsKey(requestIp)){
            Consumer<Results> deferredResultConsumer = taskMap.get(requestIp);
            deferredResultConsumer.accept(result);
            taskMap.remove(requestIp);
        }
    }

    /**
     * 保存对应的截图到服务器
     * @param requestIP
     * @param base64
     */
    public void saveImg(String requestIP ,String base64){
        Timestamp timestamp = new Timestamp(System.currentTimeMillis());
        String filename = new String(requestIP+"_"+timestamp.getTime()+".png");
        // 生成截图记录
        ScreenshotRecord screenshotRecord = new ScreenshotRecord();
        // 通过ip获取对应的员工信息
        SysUser user = sysUserMapper.selectOne(new LambdaQueryWrapper<SysUser>().eq(SysUser::getIp, requestIP));
        if (user != null){
            // 查找到对应的user插入信息
            screenshotRecord.setUserId(user.getUserId());
            screenshotRecord.setScreenshotTime(LocalDateTime.now());
            screenshotRecord.setUrl(path+filename);
            screenshotRecordMapper.insert(screenshotRecord);
        }
        BASE64Decoder decoder = new BASE64Decoder();
        try{
            // Base64解码
           byte[] bytes = decoder.decodeBuffer(base64);
            for (int i = 0; i < bytes.length; ++i) {
                if (bytes[i] < 0) {// 调整异常数据
                    bytes[i] += 256;
                }
            }
            // 生成图片
            System.out.println(filename);
            OutputStream outs = new FileOutputStream(path+filename);
            System.out.println("开始生成图片");
            outs.write(bytes);
            outs.flush();
            outs.close();
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    /**
     * 判断对应请求是否已存在
     * @param requestIp
     * @return
     */
    public boolean judgeTaskExist(String requestIp){
        System.out.println(taskMap);
        if (taskMap.containsKey(requestIp))
            return true;
        return false;
    }
}
